package scene;

import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.swing.SwingUtilities;


import scene.composants.*;
import yaut.ENV;


/**
 * Permet de rajouter un ecouteur MouseMotionListener (ecouteur souris)
 * afin de pouvoir utiliser la souris sur la scene
 * 
 * @author Delmas Gabriel
 */
public class SceneMouseManipulable extends SceneMouseAdapter
{
	
	//Menu clique droit
	//private final ClasseJPopupMenu popupEdition;
	
	IDessinableManipulable comp_source, comp_dest;
	Point pDest;
	int selectionComposant=0;

	//Permet de garder la position initial de la figure
	//private Point initialLocation;
	private boolean rectangle_selection;
	private boolean double_clique;
	
	public SceneMouseManipulable(SceneEditeur scene)
	{
		super(scene);
		composants = new ArrayList<IDessinableManipulable>();
		rectangle_selection=false;
		double_clique=false;
		//popupEdition = new ClasseJPopupMenu(this.scene);
		
		
	}

	
	public void mouseDragged(MouseEvent e)
	{	
		
		if (SwingUtilities.isLeftMouseButton(e)&&!double_clique && this.scene.getOutilSelection()==OutilPalette.SELECTION)
		{
			//if((e.getX()>0)
			  //&&(e.getY()>0)
			 // &&(e.getX()<this.scene.getDimension().width)
			 // &&(e.getY()<this.scene.getDimension().height)
			 // )		
			{
				
				for (Iterator<IDessinableManipulable> iter = composants.iterator(); iter.hasNext();)
				{
					IDessinableManipulable composant = iter.next();
					
					//Deplacement d'une extremite
					if(!composant.getExtremiteSelectionnee().isEmpty())
					{
						composant.deplacerExtremite(e.getPoint());
					}
					//Deplacement d'un objet
					else
					{
						Point p;
						Dimension dim = composant.getXYEspace();
						p = new Point(e.getPoint().x- dim.width,e.getPoint().y- dim.height);
						composant.setPosition(p);
						if(SceneEditeur.activerTransparence)
							composant.setEstTransfere(true);
					}
				}
				scene.update();
			}
			
			//Cadre de selection
			if((composants.size()==0)&&(rectangle_selection==false))
			{
				scene.definirPointDestinationRectangleSelection(e.getPoint());
				scene.update();
			}
		}
	}


	public void mousePressed(MouseEvent e)
	{		
		
		
		scene.requestFocus();
		double_clique=false;
		List<IDessinableManipulable> composantsTemp = new ArrayList<IDessinableManipulable>();
		
		//CLIQUE DROIT
		if (SwingUtilities.isRightMouseButton(e))
		{
			if(this.scene.getOutilSelection()!=OutilPalette.SELECTION)
			{
				this.scene.setOutilSelection(OutilPalette.SELECTION);
				return;
			}
			
		}
		
		
		if(this.scene.getOutilSelection()==OutilPalette.SELECTION)
		{
		boolean reclique;
		selectionComposant=0;
		comp_source=null;
		comp_dest=null;
		
		
		//CLIQUE DROIT
		if (SwingUtilities.isRightMouseButton(e))
		{
			scene.deselectionnerFigures();
			rectangle_selection=false;
			
			IDessinableManipulable composantTemp = scene.trouverComposant(e.getPoint());
			Point p=new Point(e.getX(), e.getY());
			
			//Clique droit sur une figure
			if((composantTemp!=null))
			{
				composantTemp.setEstSelectionner(true);	
				composantTemp.actionMenuContextuel(p);
				composants.clear();
				composants.add(composantTemp);
							
			}
			//Sinon clique droit sur directement sur la scene
			else
			{
				ENV.FRAME.getControleur().afficherMenuContextuel(p);
			}
			return;
		}		
		

		if (SwingUtilities.isLeftMouseButton(e))
		{
			//DOUBLE CLIQUE
			if (e.getClickCount() == 2)
			{
				IDessinableManipulable composantTemp = scene.trouverComposant(e.getPoint());
				if(composantTemp!=null)
				{
					scene.deselectionnerFigures();
					composantTemp.setEstSelectionner(true);
					composantTemp.actionDoubleClique();
					
					//On rajoute dans la liste pour deplacer
					composants.clear();
					composants.add(composantTemp);
					
					double_clique=true;
					return;
				}
			}
			
		}
		
		IDessinableManipulable composantTemp = scene.trouverComposant(e.getPoint());
		
		//On verifie si on reclique sur un figure deja selectionner pour pouvoir les deplacer
		reclique=false;
		if((composantsTemp!=null)&&(rectangle_selection))
		{
			if(composants.contains(composantTemp))
				 reclique=true;			
		}
		IDessinableManipulable composantTemp2=scene.trouverFigureSelectionner(e.getPoint());
		if(composantTemp2!=null)
		{
			composantTemp=composantTemp2;
			composants=scene.getFiguresSelectionner();
			reclique=true;
			rectangle_selection=true;
		}
			
				
			if(!reclique)
			{
				scene.deselectionnerFigures();
				/*
				for (Iterator<IDessinableManipulable> iterateur = composants.iterator(); iterateur.hasNext();)
				{
					iterateur.next().setEstSelectionner(false);
				}
				*/
				composants.clear();
				rectangle_selection=false;
			}
			else
			{
				
				for (Iterator<IDessinableManipulable> iter = composants.iterator(); iter.hasNext();)
				{
					
					IDessinableManipulable composant = iter.next();
					composant.setEstSelectionner(true);
					Dimension dim = new Dimension((e.getPoint().x-composant.getPosition().x),(e.getPoint().y-composant.getPosition().y));
					composant.setXYEspace(dim);
					
					if(composant.intersectionExtremite(e.getPoint()))
					{
						for (Iterator<IDessinableManipulable> iterateur = composants.iterator(); iterateur.hasNext();)
							iterateur.next().setEstSelectionner(false);
						
						composant.setEstSelectionner(true);
						composants.clear();
						composants.add(composant);
						break;
					}
				}
			
				
			}
		
		if((composantTemp==null)||(!rectangle_selection))
		{
			composants.clear();
			rectangle_selection=false;
			
			if((composantTemp!=null))
			{
				composants.add(composantTemp);
				composantTemp.setEstSelectionner(true);
				composantTemp.intersectionExtremite(e.getPoint());
				Dimension dim = new Dimension((e.getPoint().x-composantTemp.getPosition().x),(e.getPoint().y-composantTemp.getPosition().y));
				composantTemp.setXYEspace(dim);
				//initialLocation=composant.getPosition();
			}
			//Cadre de selection
			else
			{
					scene.initialiserRectangleSelection(e.getPoint());
			}
		}
		
		}
		if(this.scene.getOutilSelection()==OutilPalette.CREATIONCLASSE)
		{
			scene.rajouterClasse(e.getPoint());
		}
		if(this.scene.getOutilSelection()==OutilPalette.CREATIONAGGREGATION)
		{
			IDessinableManipulable composantTemp = scene.trouverComposant(e.getPoint());
				if((composantTemp!=null))
				{
					selectionComposant++;
					
					composantTemp.setEstSelectionner(true);
					if(selectionComposant==1)
						comp_source=composantTemp;
					if(selectionComposant==2)
						comp_dest=composantTemp;
					
				}
				if(selectionComposant==2)
				{
					if(comp_source.getClass()==RepresentationClasse.class && comp_dest.getClass()==RepresentationClasse.class && comp_dest!=comp_source)
					{
						scene.rajouterAggregation(e.getPoint(),(RepresentationClasse)comp_source,(RepresentationClasse)comp_dest);
						selectionComposant=0;
						comp_source.setEstSelectionner(false);
						comp_dest.setEstSelectionner(false);
						comp_source=null;
						comp_dest=null;
						//scene.setOutilActif(1);
					}
					else
					{
						selectionComposant=0;
						comp_source.setEstSelectionner(false);
						comp_dest.setEstSelectionner(false);
						comp_source=null;
						comp_dest=null;
						//scene.setOutilActif(1);
					}
				}
		}
		if(this.scene.getOutilSelection()==OutilPalette.CREATIONCOMPOSITION)
		{
			IDessinableManipulable composantTemp = scene.trouverComposant(e.getPoint());
				if((composantTemp!=null))
				{
					selectionComposant++;
					
					composantTemp.setEstSelectionner(true);
					if(selectionComposant==1)
						comp_source=composantTemp;
					if(selectionComposant==2)
						comp_dest=composantTemp;
					
				}
				if(selectionComposant==2)
				{
					if(comp_source.getClass()==RepresentationClasse.class && comp_dest.getClass()==RepresentationClasse.class && comp_dest!=comp_source)
					{
						scene.rajouterComposition(e.getPoint(),(RepresentationClasse)comp_source,(RepresentationClasse)comp_dest);
						selectionComposant=0;
						comp_source.setEstSelectionner(false);
						comp_dest.setEstSelectionner(false);
						comp_source=null;
						comp_dest=null;
						//scene.setOutilActif(1);
					}
					else
					{
						selectionComposant=0;
						comp_source.setEstSelectionner(false);
						comp_dest.setEstSelectionner(false);
						comp_source=null;
						comp_dest=null;
						//scene.setOutilActif(1);
					}
				}
		}
		if(this.scene.getOutilSelection()==OutilPalette.CREATIONHERITAGE)
		{
			IDessinableManipulable composantTemp = scene.trouverComposant(e.getPoint());
			if((composantTemp!=null))
			{
				selectionComposant++;
				
				composantTemp.setEstSelectionner(true);
				if(selectionComposant==1)
					comp_source=composantTemp;
				if(selectionComposant==2)
					comp_dest=composantTemp;
				
			}
			if(selectionComposant==2)
			{
				if(comp_source.getClass()==RepresentationClasse.class && comp_dest.getClass()==RepresentationClasse.class && comp_dest!=comp_source)
				{
					scene.rajouterHeritage(e.getPoint(),(RepresentationClasse)comp_source,(RepresentationClasse)comp_dest);
					selectionComposant=0;
					comp_source.setEstSelectionner(false);
					comp_dest.setEstSelectionner(false);
					comp_source=null;
					comp_dest=null;
				}
				else
				{
					selectionComposant=0;
					comp_source.setEstSelectionner(false);
					comp_dest.setEstSelectionner(false);
					comp_source=null;
					comp_dest=null;
				}
			}
		}
		if(this.scene.getOutilSelection()==OutilPalette.CREATIONLIENNOTE)
		{
			IDessinableManipulable composantTemp = scene.trouverComposant(e.getPoint());
			if((composantTemp!=null)||selectionComposant==1)
			{
				if(composantTemp!=null)
					composantTemp.setEstSelectionner(true);
				
				if(selectionComposant==1)
				{
					pDest=e.getPoint();
					selectionComposant=2;
				}
				if(selectionComposant==0&&composantTemp.getClass()==RepresentationNote.class)
				{
					comp_source=composantTemp;
					pDest=new Point(0,0);
					selectionComposant=1;
				}
				
			}
			if(selectionComposant==2)
			{
					scene.rajouterLienNote((RepresentationNote)comp_source,e.getPoint());
					selectionComposant=0;
					comp_source.setEstSelectionner(false);
					comp_source=null;
					pDest=null;
				
				
			}
		}
		if(this.scene.getOutilSelection()==OutilPalette.CREATIONNOTE)
		{
			scene.rajouterNote(e.getPoint());
		}

	}

	
	public void mouseReleased(MouseEvent e)
	{
		if (SwingUtilities.isLeftMouseButton(e))
		{
			deselectionnerComposants();
		
			//On vide la liste des composants
			if(rectangle_selection==false)
				composants.clear();
			
			
			//On efface le rectangle de selection
			List<IDessinableManipulable> composantsTemp=scene.detruireRectangleSelection();
			if(composantsTemp.size()!=0)
			{
				composants=composantsTemp;
				rectangle_selection=true;
			}
			else if((rectangle_selection==true)&&(composants.size()==0)) rectangle_selection=false;
	
		}
		
		scene.update();
	}

	private void deselectionnerComposants()
	{
		for (Iterator<IDessinableManipulable> iter = composants.iterator(); iter.hasNext();)
		{
			IDessinableManipulable composant = iter.next();
			if(composant.getExtremiteSelectionnee()!="")
			{
				composant.relacherExtremites();
				composant.setExtremiteSelectionnee("");
			}
			composant.setEstTransfere(false);
		}
	}
	
}
